﻿using Autofac;
using Autofac.Integration.WebApi;
using Pay.Core;
using Pay.IService;
using Pay.Service;
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace Pay.Token {
    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
    public class ThrottleAttribute : ActionFilterAttribute {
        /// <summary>
        /// 限定时长
        /// </summary>
        public int Seconds { get; set; }
        /// <summary>
        /// 限次数
        /// </summary>
        public int Times { get; set; }
        /// <summary>
        /// 获取或设置值作为HTTP状态代码返回，因为由于限制策略拒绝请求。 默认值为429（太多请求）。
        /// </summary>
        public HttpStatusCode QuotaExceededResponseCode { get; set; }
        private IUnitOfWork _iUnitOfWork;
        private IIPFilterService _iPFilterService;
        public ThrottleAttribute(int seconds = 0, int times = 0) {
            Seconds = seconds;
            Times = times;
            QuotaExceededResponseCode = (HttpStatusCode)429;
        }
        public override void OnActionExecuting(HttpActionContext actionContext) {
            var requestScope = actionContext.Request.GetDependencyScope();
            var requestLifetimeScope = requestScope.GetRequestLifetimeScope();
            _iUnitOfWork = requestLifetimeScope.Resolve<IUnitOfWork>();
            _iPFilterService = requestLifetimeScope.Resolve<IIPFilterService>();

            var controllerName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            var actionName = actionContext.ActionDescriptor.ActionName;
            var ip = IPHelper.IPAddress;
            var ipModel = _iPFilterService.GetIP(ip);
            if (ipModel != null && ipModel.is_wihte_ip == false) { throw new ServerErrorException("您的IP已被加入黑名单限制访问！"); }
            if (ipModel != null && ipModel.is_wihte_ip) return;
            //if (ip.StartsWith("192.168")) ip = Dns.GetHostName() + ip;
            var log = IocHelper.Get<ILogHelper>("info");
            log.Info("注册请求ip:" + ip);
            var key = string.Format("{0}-{1}-{2}", ip, controllerName, actionName);
            var time = _iUnitOfWork.GetCache<int>(key);
            if (time > 0) {
                _iUnitOfWork.SetCache(key, (int)time + 1, Seconds);
                if ((int)time >= Times) {
                    log.Info("注册请求ip频繁:" + ip + "次数：" + time);
                    if ((int)time >= 100) {
                        _iPFilterService.AddIp(ip, false);
                    }
                    throw new ServerErrorException("您操作过于频繁，请稍后再试", 429);
                }
            } else {
                _iUnitOfWork.SetCache(key, 1, Seconds);
            }
            base.OnActionExecuting(actionContext);
        }

    }
}